#pragma once

#include <string>
#include <vector>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <jsoncpp/json/json.h>
#include "Util.hpp"

// #define MYSELF

namespace protocol_ns
{
#define SEP " "
// 前者是函数，后者是关键字
#define SEP_LEN strlen(SEP) // 决定不能使用 sizeof
#define HEAD_SEP "\r\n"
#define HEAD_SEP_LEN strlen(HEAD_SEP)
    // "7"/r/n"10 + 20"/r/n
    std::string AddHeader(const std::string &str)
    {
        std::string len_string = std::to_string(str.size());

        std::string ret;

        ret = len_string + HEAD_SEP + str + HEAD_SEP;
        return ret;
    }

    std::string RemoveHeader(const std::string &str, size_t len)
    {
        // 反向截取有效数据
        return str.substr(str.size() - HEAD_SEP_LEN - len, len);
    }

    int ReadPackage(std::string &inbuffer, std::string *package)
    {
        auto pos = inbuffer.find(HEAD_SEP);
        if (pos == std::string::npos)
            return 0; // 未找到目标字符串
        std::string lenStr = inbuffer.substr(0, pos);
        int totalLen = lenStr.size() + HEAD_SEP_LEN * 2 + Util::ToInt(lenStr);

        if (inbuffer.size() < totalLen)
            return 0; // 理论字符串和实际字符串不相同，需重新读取
        *package = inbuffer.substr(0, totalLen);
        inbuffer.erase(0, totalLen);

        return Util::ToInt(lenStr);
    }

    class Request
    {
    public:
        // 无参构造
        Request()
        {
        }
        Request(int x, int y, char op)
            : _x(x), _y(y), _op(op)
        {
        }
        // struct -> string
        void Serialize(std::string *outStr)
        {
            *outStr = "";
#ifdef MYSELF
            std::string x_str = std::to_string(_x);
            std::string y_str = std::to_string(_y);

            *outStr = x_str + SEP + _op + SEP + y_str;
#else
            Json::Value root; // Value: 一种万能对象，可接收任意KV关系

            root["x"] = _x;
            root["y"] = _y;
            root["op"] = _op;

            // Json::FastWriter writer;
            Json::StyledWriter writer;
            *outStr = writer.write(root);
#endif
        }
        // string -> struct
        bool Deserialize(const std::string &inStr)
        {
// string -> vector 字符串切割
#ifdef MYSELF
            std::vector<std::string> tmp;
            Util::StringSplit(&tmp, SEP, inStr);

            // 差错判断
            if (tmp.size() != 3)
                return false;
            if (tmp[1].size() != 1)
                return false;

            _x = Util::ToInt(tmp[0]);
            _op = tmp[1][0];
            _y = Util::ToInt(tmp[2]);
#else
            Json::Value root;
            Json::Reader reader;

            reader.parse(inStr, root); // 把Josn串重新转化成root对象

            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _op = root["op"].asInt();

#endif
            return true;
        }

        ~Request()
        {
        }

    public:
        // 差错判断 10 / 0 ?
        int _x;
        int _y;
        char _op;
    };

    class Response
    {
    public:
        Response()
        {
        }
        Response(int result, int code)
            : _result(result), _code(code)
        {
        }
        // struct -> string
        void Serialize(std::string *outStr)
        {
            // 20 1
            *outStr = "";
#ifdef MYSELF
            std::string result_str = std::to_string(_result);
            std::string code_str = std::to_string(_code);

            *outStr = result_str + SEP + code_str;
#else
            Json::Value root;
            root["result"] = _result;
            root["code"] = _code;

            // Json::FastWriter writer;
            Json::StyledWriter writer;
            *outStr = writer.write(root);
#endif
        }
        // string -> struct
        bool Deserialize(const std::string &inStr)
        {
#ifdef MYSELF
            std::vector<std::string> tmp;
            Util::StringSplit(&tmp, SEP, inStr);

            if (tmp.size() != 2)
                return false;

            _result = Util::ToInt(tmp[0]);
            _code = Util::ToInt(tmp[1]);
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(inStr, root);

            _result = root["result"].asInt();
            _code = root["code"].asInt();

#endif
            return true;
        }

        ~Response()
        {
        }

    public:
        int _result;
        int _code; // 运算合法性判断
    };
}